home *** CD-ROM | disk | FTP | other *** search
/ Monster Media 1996 #15 / Monster Media Number 15 (Monster Media)(July 1996).ISO / math / differ.zip / DIFFER.C < prev    next >
C/C++ Source or Header  |  1996-04-06  |  5KB  |  196 lines

  1. /*
  2.    DIFFER :
  3.    This program was written to help with differentiation. It accepts
  4.    algebraic expressions with support for a number of functions and will
  5.    differentiate the expression with respect to x. A documentation file
  6.    is included, as is an example of how to set the program up with a list
  7.    of expressions and run it from a batch file.
  8.  
  9.    This program was written by Paul Young, using Turbo C++.
  10.    I accept no responsibility for use or misuse of this program in any way.
  11.    This program is Public Domain.
  12.    It may be copied freely provided this notice is included.
  13.    This program may be used as a base or included in other programs
  14.    however these programs must also be Public Domain and no monetary gain
  15.    should be made from these. Help support Public Domain programming.
  16.    P Young, 101716.3323@compuserve.com
  17. */
  18.  
  19. #include "differ.h"
  20.  
  21. #define BACKSPACE 8
  22. #define ENTER 13
  23.  
  24. struct expression *topexpress;
  25.  
  26. typedef enum{QUIT,SIMPLIFY,PRINT,DIFF,INPUT,EXPR,GO,AGAIN,BATCH,ERRORINP} symbol;
  27.  
  28. /*
  29.   Here is our list of commands.
  30. */
  31.  
  32. struct sorders
  33. { char *name;
  34.   symbol command;
  35. } orders[] =
  36. {  {"quit",QUIT},
  37.    {"simplify",SIMPLIFY},
  38.    {"print",PRINT},
  39.    {"diff",DIFF},
  40.    {"input",INPUT},
  41.    {"expr",EXPR},
  42.    {"go",GO},
  43.    {"again",AGAIN},
  44.    {"batch",BATCH},
  45.    {NULL,ERRORINP}
  46. };
  47.  
  48. char buffer[MAXINPLINELEN*2];
  49.  
  50. /*
  51.   puts a prompt to the screen
  52. */
  53.  
  54. void doprompt(void)
  55. { textcolor(CYAN);
  56.   cprintf("Command> ");
  57.   textcolor(LIGHTGRAY);
  58. }
  59.  
  60. /*
  61.   a useful routine to return an unwanted expression to the heap.
  62.   recursive, as are a lot of the routines
  63. */
  64.  
  65. void freetree(struct expression *expr)
  66. { if(expr==NULL) return;
  67.   if(expr->lval!=NULL) freetree(expr->lval);
  68.   if(expr->rval!=NULL) freetree(expr->rval);
  69.   if(expr!=NULL) free(expr);
  70. }
  71.  
  72. /*
  73.   this is just the input routine. nothing fancy.
  74. */
  75.  
  76. char *getinput(void)
  77. { int buffpt=0;
  78.   logical inputdone=FALSE;
  79.   char inpchar;
  80.   buffer[0]=0;
  81.   _setcursortype(_NORMALCURSOR);
  82.   while(!inputdone)
  83.   { inpchar=getch();
  84.     if((inpchar==BACKSPACE)&&(buffpt))
  85.     { buffer[--buffpt]=0;
  86.     cprintf("\b \b");
  87.     }
  88.     else if((inpchar==ENTER)&&(buffpt))
  89.     { inputdone=TRUE;
  90.     cprintf("\n\r");
  91.     }
  92.     else if((isprint(inpchar))&&(buffpt<(MAXINPLINELEN-1)))
  93.     { buffer[buffpt++]=inpchar;
  94.     buffer[buffpt]=0;
  95.     cprintf("%c",inpchar);
  96.     }
  97.   }
  98.   _setcursortype(_NOCURSOR);
  99.   return buffer;
  100. }
  101.  
  102. /*
  103.    This searches for the command entered and calls the appropriate routine.
  104.    returns true when quit is entered
  105. */
  106.  
  107. logical parseinput(char *inpline)
  108. { int buffpt=0,
  109.     optnum=0;
  110.   logical found=FALSE;
  111.   while(inpline[buffpt]==' ')buffpt++;
  112.   while((orders[optnum].name!=NULL)&&(!found))
  113.   { if(!strnicmp(orders[optnum].name,&inpline[buffpt],strlen(orders[optnum].name)))
  114.     found=TRUE;
  115.     else optnum++;
  116.   }
  117.   if(!found)
  118.   { cprintf("Command unknown\n\r");
  119.     return FALSE;
  120.   }
  121.   else
  122.   { switch(orders[optnum].command)
  123.     { case QUIT:    return TRUE;
  124.     case SIMPLIFY:topexpress=simplify(topexpress);
  125.               break;
  126.     case PRINT:   printout(topexpress);
  127.               printf("\n\r");
  128.               break;
  129.     case DIFF:    topexpress=differentiate(topexpress);
  130.               break;
  131.     case EXPR:
  132.     case INPUT:   freetree(topexpress);
  133.               topexpress=parser(&inpline[buffpt+strlen(orders[optnum].name)]);
  134.               break;
  135.     case GO:      freetree(topexpress);
  136.               topexpress=parser(&inpline[buffpt+strlen(orders[optnum].name)]);
  137.               topexpress=differentiate(topexpress);
  138.               topexpress=simplify(topexpress);
  139.               printout(topexpress);
  140.               printf("\n\r");
  141.               break;
  142.     case AGAIN:   topexpress=differentiate(topexpress);
  143.               topexpress=simplify(topexpress);
  144.               printout(topexpress);
  145.               printf("\n\r");
  146.               break;
  147.     case BATCH:   freetree(topexpress);
  148.               topexpress=parser(&inpline[buffpt+strlen(orders[optnum].name)]);
  149.               printf("Input expression:\n\r");
  150.               printout(topexpress);
  151.               printf("\n\r");
  152.               printf("Output expression:\n\r");
  153.               topexpress=differentiate(topexpress);
  154.               topexpress=simplify(topexpress);
  155.               printout(topexpress);
  156.               printf("\n\r\n\r");
  157.               break;
  158.     case ERRORINP:cprintf("Unknown Command\n\r");
  159.               break;
  160.     default:      cprintf("Internal Error 1\n\rType 'quit' to quit\n\r");
  161.               break;
  162.     }
  163.   }
  164.   return FALSE;
  165. }
  166.  
  167. /*
  168.    prompt,get input and parse it.
  169. */
  170.  
  171. logical command(void)
  172. { char *inpline;
  173.   doprompt();
  174.   inpline=getinput();
  175.   return parseinput(inpline);
  176. }
  177.  
  178. /*
  179.    the main function - a repeated loop until quit is entered.
  180. */
  181.  
  182. int main(void)
  183. { topexpress=NULL;
  184.   clrscr();
  185.   textcolor(RED);
  186.   cprintf("Algebraic Differentiator Program v1.0\n\r");
  187.   cprintf("By Paul Young\n\r");
  188.   cprintf("Public Domain\n\r\n\r");
  189.   textcolor(LIGHTGRAY);
  190.   do
  191.   {} while (!command());
  192.   cprintf("Thanks for using the algebraic differentiator.\n\r");
  193.   _setcursortype(_NORMALCURSOR);
  194.   return(0);
  195. }
  196.